/*
 * Copyright 2010-2011 Sanjay Dwivedi.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.isdinvestments.cam.test.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import javax.validation.Validator;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import com.isdinvestments.cam.application.CustomerService;
import com.isdinvestments.cam.application.CustomerServiceImpl;
import com.isdinvestments.cam.infrastructure.repository.CustomerRepository;

/*
 * Cannot make JavaConfig work with Spring Data project. Need to come back to fix 
 * the use of JavaConfig. Until then use XML based Spring container configuration.
 * 
 */
@Configuration
@ImportResource("classpath:camTestApplicationContext.xml")
public class CamTestConfig {
	private @Value("${database.url}") String databaseUrl;
	private @Value("${database.username}") String databaseUsername;
	private @Value("${database.password}") String databasePassword;
	private @Value("${database.driverClassName}") String databaseDriverClass;
	
	public @Bean DataSource dataSource() {
		DriverManagerDataSource ds = new DriverManagerDataSource(databaseUrl, databaseUsername, databasePassword);
		ds.setDriverClassName(databaseDriverClass);
		return ds;
	}
	
	public @Bean PersistenceExceptionTranslationPostProcessor jpaExceptionTranslationPostProcessor() {
		return new PersistenceExceptionTranslationPostProcessor();
	}
	
	public @Bean PersistenceAnnotationBeanPostProcessor jpaAnnotationBeanPostProcessor() {
		return new PersistenceAnnotationBeanPostProcessor();
	}
	
	public @Bean JpaVendorAdapter jpaAdapter() {
		return new HibernateJpaVendorAdapter();
	}

    public @Bean EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setJpaVendorAdapter(jpaAdapter());
        em.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
        em.afterPropertiesSet();
        
        return em.getNativeEntityManagerFactory();
    }
    
//    public @Bean LocalContainerEntityManagerFactoryBean  entityManagerFactoryFactoryBean() {
//        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
//        em.setDataSource(dataSource());
//        em.setJpaVendorAdapter(jpaAdapter());
//        em.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
//        em.afterPropertiesSet();
//        
//        return em;
//    }

    public @Bean PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }
    
    public @Bean Validator validator() {
    	return new LocalValidatorFactoryBean();
    }

    public @Bean CustomerService customerService() {
    	return new CustomerServiceImpl();
    }
    
}
